package net.qiujuer.genius.blur.frags;

import net.qiujuer.genius.blur.ResourceTable;
import net.qiujuer.genius.blur.StackBlur;
import net.qiujuer.genius.blur.utils.AnimatorValueUtils;
import net.qiujuer.genius.blur.utils.PixelMapUtils;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.element.PixelMapElement;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.image.PixelMap;

public class AnimFragment extends BaseFragment
        implements Component.BindStateChangedListener {

    private int mLeft;
    private int mWidth;
    private AnimatorGroup mSet;
    private AnimatorProperty mMoveToLeftAnim;
    private AnimatorProperty mMoveToRightAnim;
    private boolean fromStart = true;

    public AnimFragment(Context context) {
        super(context);
    }

    public AnimFragment(Context context, AttrSet attrSet) {
        super(context, attrSet);
    }

    public AnimFragment(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
    }

    @Override
    protected void onCreateView() {
        LayoutScatter.getInstance(getContext())
                .parse(ResourceTable.Layout_fragment_blur_anim, this, true);
        mText = (Text) findComponentById(ResourceTable.Id_text);
        setClickedListener(this);
    }

    @Override
    public void onClick(Component component) {
        if (mSet != null && mSet.isRunning()) {
            return;
        }
        animView();
    }

    @Override
    protected void blur() {
        if (mBitmap == null || mWidth == 0 || mText == null) {
            return;
        }
        PixelMap bitmap = cropTextBitmap(mBitmap);
        bitmap = getScaleBitmap(bitmap);
        long startTime = System.currentTimeMillis();
        final PixelMap ret = blur(bitmap, 2);
        show(ret, System.currentTimeMillis() - startTime);
    }

    @Override
    protected PixelMap blur(PixelMap bitmap, int radius) {
        return StackBlur.blur(bitmap, radius, true);
    }

    @Override
    protected void show(PixelMap bitmap, long time) {
        if (mText != null) {
            new EventHandler(EventRunner.getMainEventRunner())
                    .postTask(new Runnable() {
                        @Override
                        public void run() {
                            if (mText != null) {
                                PixelMapElement element = new PixelMapElement(bitmap);
                                mText.setBackground(element);
                            }
                        }
                    });
        }
    }

    private PixelMap cropTextBitmap(PixelMap bitmap) {
        int h = bitmap.getImageInfo().size.height;
        return PixelMapUtils.createBitmap(bitmap,
                mLeft,
                0,
                mWidth,
                h,
                null,
                false);
    }


    @Override
    public void onComponentBoundToWindow(Component component) {

    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {
        if (mSet != null) {
            mSet.cancel();
        }
    }

    public void animView() {
        if (mSet == null) {
            mWidth = mText.getWidth();
            final AnimatorValue topAnim = new AnimatorValue();
            topAnim.setLoopedCount(9);
            topAnim.setLoopedListener(new Animator.LoopedListener() {
                @Override
                public void onRepeat(Animator animator) {
                    fromStart = !fromStart;
                    if (fromStart) {
                        mMoveToRightAnim.start();
                    } else {
                        mMoveToLeftAnim.start();
                    }
                }
            });
            topAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                @Override
                public void onUpdate(AnimatorValue animatorValue, float v) {
                    double value = 0;
                    if (fromStart) {
                        value = AnimatorValueUtils.getAnimatedValue(v, 0, getRight() - mWidth);
                    }else {
                        value = AnimatorValueUtils.getAnimatedValue(v, getRight() - mWidth, 0);
                    }
                    mLeft = (int) value;
                    blur();
                }
            });

            final AnimatorProperty toRightAnim = new AnimatorProperty();
            toRightAnim.setTarget(mText)
                    .moveFromX(0)
                    .setDuration(2800)
                    .moveToX(getRight() - mWidth);

            final AnimatorProperty toLeftAnim = new AnimatorProperty();
            toLeftAnim.setTarget(mText)
                    .moveFromX(getRight() - mWidth)
                    .setDuration(2800)
                    .moveToX(0);

            AnimatorGroup set = new AnimatorGroup();
            set.runParallel(topAnim);
            set.setDuration(2800);
            set.start();
            toRightAnim.start();
            mSet = set;
            mMoveToRightAnim = toRightAnim;
            mMoveToLeftAnim = toLeftAnim;
        } else {
            fromStart = true;
            mSet.start();
            mMoveToRightAnim.start();
        }
    }
}
